{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "946aa78d",
   "metadata": {},
   "source": [
    "### DQN解决倒立摆问题"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a901585b-ae5e-45ac-8b38-fc996749807e",
   "metadata": {},
   "source": [
    "😋😋公众号算法美食屋后台回复关键词：**torchkeras**，获取本文notebook源代码和数据集下载链接。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6546c403",
   "metadata": {},
   "source": [
    "表格型方法存储的状态数量有限，当面对围棋或机器人控制这类有数不清的状态的环境时，表格型方法在存储和查找效率上都受局限，DQN的提出解决了这一局限，**使用神经网络来近似替代Q表格**。\n",
    "\n",
    "本质上DQN还是一个Q-learning算法，更新方式一致。为了更好的探索环境，同样的也采用epsilon-greedy方法训练。\n",
    "\n",
    "在Q-learning的基础上，DQN提出了两个技巧使得Q网络的更新迭代更稳定。\n",
    "\n",
    "* 经验回放(Experience Replay): 使用一个经验池存储多条经验s,a,r,s'，再从中随机抽取一批数据送去训练。\n",
    "\n",
    "* 固定目标(Fixed Q-Target): 复制一个和原来Q网络结构一样的Target-Q网络，用于计算Q目标值。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0577e68",
   "metadata": {},
   "source": [
    "### 一，准备环境"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c40ab52c",
   "metadata": {},
   "source": [
    "gym是一个常用的强化学习测试环境，可以用make创建环境。\n",
    "\n",
    "env具有reset,step,render几个方法。\n",
    "\n",
    "\n",
    "**倒立摆问题** \n",
    "\n",
    "环境设计如下：\n",
    "\n",
    "倒立摆问题环境的状态是无限的，用一个4维的向量表示state.\n",
    "\n",
    "4个维度分别代表如下含义\n",
    "\n",
    "* cart位置：-2.4 ~ 2.4\n",
    "* cart速度：-inf ~ inf\n",
    "* pole角度：-0.5 ～ 0.5 （radian）\n",
    "* pole角速度：-inf ~ inf\n",
    "\n",
    "智能体设计如下：\n",
    "\n",
    "智能体的action有两种，可能的取值2种：\n",
    "\n",
    "* 0，向左\n",
    "* 1，向右\n",
    "\n",
    "奖励设计如下：\n",
    "\n",
    "每维持一个步骤，奖励+1，到达200个步骤，游戏结束。\n",
    "\n",
    "所以最高得分为200分。\n",
    "\n",
    "倒立摆问题希望训练一个智能体能够尽可能地维持倒立摆的平衡。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "283986f4-3585-4e22-9ed7-f20a29916424",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "gym.__version__= 0.26.2\n"
     ]
    }
   ],
   "source": [
    "import gym \n",
    "import numpy as np \n",
    "import pandas as pd \n",
    "import time\n",
    "import matplotlib\n",
    "import matplotlib.pyplot as plt\n",
    "from IPython import display\n",
    "\n",
    "print(\"gym.__version__=\",gym.__version__)\n",
    "\n",
    "\n",
    "%matplotlib inline\n",
    "\n",
    "#可视化函数：\n",
    "def show_state(env, step, info=''):\n",
    "    plt.figure(num=10086,dpi=100)\n",
    "    plt.clf()\n",
    "    plt.imshow(env.render())\n",
    "    plt.title(\"step: %d %s\" % (step, info))\n",
    "    plt.axis('off')\n",
    "    display.clear_output(wait=True)\n",
    "    display.display(plt.gcf())\n",
    "    plt.close()\n",
    "    \n",
    "\n",
    "env = gym.make('CartPole-v1',render_mode=\"rgb_array\") # CartPole-v0: 预期最后一次评估总分 > 180（最大值是200）\n",
    "env.reset()\n",
    "action_dim = env.action_space.n   # CartPole-v0: 2\n",
    "obs_shape = env.observation_space.shape   # CartPole-v0: (4,)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "519bc64e-66a9-40a4-81bb-1d85e2cb8bf8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAgMAAAF0CAYAAAC+FDqzAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAV0klEQVR4nO3de4zcdb3w8c9vZndnb+1uF3qnF8EWKoVykXIEFI9aUvKIGu/X5CRG5AG8RpuTmIiSSIIE8Q+C8fEf/lASq6JGKgeDQTw8EKDgw6HYWhAsvdJur7vd68z8nj849liLnUXY2Z35vl5JE5j97Oxnm8z0nd/85jdZnud5AADJKkz1AgDA1BIDAJA4MQAAiRMDAJA4MQAAiRMDAJA4MQAAiRMDAJA4MQAAiRMDAJA4MQDT1F133RXf/e53p3qNEwwODsYNN9wQa9eujb6+vsiyLO68885/OL958+ZYu3ZtdHd3R19fX3zqU5+Kffv21W9hoCYxANPUdI2B/v7+uPHGG2Pz5s2xatWqk87u2LEj3va2t8Vzzz0XN910U3zlK1+JDRs2xJo1a2JsbKxOGwO1tEz1AkBjmT9/fuzevTvmzZsXGzdujIsuuugfzt50001x9OjReOKJJ2Lx4sUREbF69epYs2ZN3HnnnXH11VfXa23gJBwZgCkwMDAQX/ziF2Pp0qVRKpVizpw5sWbNmnjyyScjIuLtb397bNiwIbZt2xZZlkWWZbF06dJj3z86Oho33HBDvPGNb4xSqRSLFi2KdevWxejo6HE/J8uyuP766+NHP/pRnHnmmdHe3h4XXnhh/P73vz9hpy1btsSLL75Yc/dSqRTz5s2b0O/5s5/9LN797ncfC4GIiHe9612xfPnyWL9+/YTuA5h8jgzAFLjmmmvipz/9aVx//fXxpje9Kfbv3x8PPfRQbN68OS644IL42te+FocPH44dO3bEbbfdFhER3d3dERFRrVbjPe95Tzz00ENx9dVXx4oVK+Lpp5+O2267LbZu3Rq/+MUvjvtZDz74YPz4xz+Oz3/+81EqleKOO+6ItWvXxmOPPRYrV648NrdixYq4/PLL43e/+93r8jvu3Lkz9u7dG29+85tP+Nrq1avj17/+9evyc4DXTgzAFNiwYUN85jOfiVtvvfXYbevWrTv232vWrImFCxfGwYMH45Of/ORx33vXXXfF/fffHw8++GBcdtllx25fuXJlXHPNNfHwww/HJZdccuz2TZs2xcaNG+PCCy+MiIiPfvSjceaZZ8bXv/71uPvuuyfrV4zdu3dHxMsvK/y9+fPnx4EDB2J0dDRKpdKk7QBMjBiAKdDb2xuPPvpo7Nq1KxYsWPCqvvcnP/lJrFixIs4666zo7+8/dvs73vGOiIh44IEHjouBt7zlLcdCICJi8eLF8d73vjd+9atfRaVSiWKxGBEReZ6/ll/pBMPDwxERr/iPfXt7+7EZMQBTzzkDMAW+/e1vx6ZNm2LRokWxevXq+MY3vhHPP//8hL732WefjWeeeSZmz5593J/ly5dHRMTevXuPm1+2bNkJ97F8+fIYGhqa1Lf4dXR0RESccB5DRMTIyMhxM8DUcmQApsCHP/zheOtb3xo///nP4ze/+U3ccsstcfPNN8fdd98dV1555Um/t1qtxjnnnBPf+c53XvHrixYtmoyVX7W/vjzw15cL/tbu3bujr6/PUQGYJsQATJH58+fHtddeG9dee23s3bs3LrjggvjWt751LAayLHvF7zvjjDPiqaeeine+853/cOZvPfvssyfctnXr1ujs7IzZs2e/tl/iJBYuXBizZ8+OjRs3nvC1xx57LM4777xJ+9nAq+NlAqizSqUShw8fPu62OXPmxIIFC447pN7V1XXCXMTLRxV27twZP/jBD0742vDwcBw9evS42x555JFjb1mMiNi+fXv88pe/jCuuuOLY+QIRE39r4avxgQ98IO65557Yvn37sdt++9vfxtatW+NDH/rQ6/qzgH9elr/eZw0BJ3Xo0KE47bTT4oMf/GCsWrUquru74/7774/169fHrbfeGl/+8pcjIuKWW26JdevWxZe+9KW46KKLoru7O6666qqoVqtx1VVXxb333hsf+chH4tJLL41KpRJbtmyJ9evXx3333Xfs7XxZlsXKlStjz549x7218KWXXopHH300zj333GN7ZVk24bcW3n777XHo0KHYtWtXfO9734v3v//9cf7550dExOc+97no6emJiJfD4/zzz4/e3t74whe+EIODg3HLLbfEaaedFo8//riXCWC6yIG6Gh0dzb/61a/mq1atymfMmJF3dXXlq1atyu+4447j5gYHB/OPf/zjeW9vbx4R+ZIlS459bWxsLL/55pvzs88+Oy+VSvmsWbPyCy+8MP/mN7+ZHz58+NhcROTXXXdd/sMf/jBftmxZXiqV8vPPPz9/4IEHTtgrIvLLL798Qr/DkiVL8oh4xT8vvPDCcbObNm3Kr7jiiryzszPv7e3NP/GJT+R79uyZ6F8XUAeODEATy7Isrrvuurj99tunehVgGnPOAAAkTgwAQOLEAAAkznUGoIk5JQiYCEcGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxYgAAEicGACBxLVO9ADC1qpVyZFkWEVlEFhGR/ff/A6kQA5CwaqUcm9bfEMW2juiavSQ6T10SXbOXREt7VxRa2qJQbItCS2tkheJUrwpMIjEACRvqfzEq46MxemRfDPW/GBH/GRERbd2nRMes+dHeOy/ae+fFrNMviNb2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\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "env.reset()\n",
    "done = False\n",
    "step = 0\n",
    "while not done:\n",
    "    \n",
    "    action = np.random.randint(0, 1)\n",
    "    state,reward,done,truncated,info = env.step(action)\n",
    "    step+=1\n",
    "    print(state,reward)\n",
    "    time.sleep(1.0)\n",
    "    #env.render() \n",
    "    show_state(env,step=step)\n",
    "    #print('step {}: action {}, state {}, reward {}, done {}, truncated {}, info {}'.format(\\\n",
    "    #        step, action, state, reward, done, truncated,info))\n",
    "    \n",
    "display.clear_output(wait=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3bc6b673",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "86a5c44a",
   "metadata": {},
   "source": [
    "### 二，定义Agent "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "09ff500b",
   "metadata": {},
   "source": [
    "DQN的核心思想为使用一个神经网络来近似替代Q表格。\n",
    "\n",
    "Model: 模型结构, 负责拟合函数 Q(s,a)。主要实现forward方法。\n",
    "\n",
    "Agent:智能体，负责学习并和环境交互, 输入输出是numpy.array形式。有sample(单步采样), predict(单步预测), 有predict_batch(批量预测), compute_loss(计算损失), sync_target(参数同步)等方法。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "e71d72fd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[-0.1148,  0.0068],\n",
       "        [-0.1311,  0.0315]], grad_fn=<AddmmBackward0>)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import torch \n",
    "from torch import nn\n",
    "import torch.nn.functional as F\n",
    "import copy \n",
    "\n",
    "class Model(nn.Module):\n",
    "    def __init__(self, obs_dim, action_dim):\n",
    "        \n",
    "        # 3层全连接网络\n",
    "        super(Model, self).__init__()\n",
    "        self.obs_dim = obs_dim\n",
    "        self.action_dim = action_dim \n",
    "        self.fc1 = nn.Linear(obs_dim,32)\n",
    "        self.fc2 = nn.Linear(32,16)\n",
    "        self.fc3 = nn.Linear(16,action_dim)\n",
    "\n",
    "    def forward(self, obs):\n",
    "        # 输入state，输出所有action对应的Q，[Q(s,a1), Q(s,a2), Q(s,a3)...]\n",
    "        x = self.fc1(obs)\n",
    "        x = torch.tanh(x)\n",
    "        x = self.fc2(x)\n",
    "        x = torch.tanh(x)\n",
    "        Q = self.fc3(x)\n",
    "        return Q\n",
    "    \n",
    "model = Model(4,2)\n",
    "model_target = copy.deepcopy(model)\n",
    "\n",
    "model.eval()\n",
    "model.forward(torch.tensor([[0.2,0.1,0.2,0.0],[0.3,0.5,0.2,0.6]]))\n",
    "\n",
    "model_target.eval() \n",
    "model_target.forward(torch.tensor([[0.2,0.1,0.2,0.0],[0.3,0.5,0.2,0.6]]))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "3a702800",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch \n",
    "from torch import nn \n",
    "import copy \n",
    "\n",
    "class DQNAgent(nn.Module):\n",
    "    def __init__(self, model, \n",
    "        gamma=0.9,\n",
    "        e_greed=0.1,\n",
    "        e_greed_decrement=0.001\n",
    "        ):\n",
    "        super().__init__()\n",
    "        \n",
    "        self.model = model\n",
    "        self.target_model = copy.deepcopy(model)\n",
    "  \n",
    "        self.gamma = gamma # reward 的衰减因子，一般取 0.9 到 0.999 不等\n",
    "        \n",
    "        self.e_greed = e_greed  # 有一定概率随机选取动作，探索\n",
    "        self.e_greed_decrement = e_greed_decrement  # 随着训练逐步收敛，探索的程度慢慢降低\n",
    "        \n",
    "        self.global_step = 0\n",
    "        self.update_target_steps = 200 # 每隔200个training steps再把model的参数复制到target_model中\n",
    "        \n",
    "        \n",
    "    def forward(self,obs):\n",
    "        return self.model(obs)\n",
    "    \n",
    "    @torch.no_grad()\n",
    "    def predict_batch(self, obs):\n",
    "        \"\"\" 使用self.model网络来获取 [Q(s,a1),Q(s,a2),...]\n",
    "        \"\"\"\n",
    "        self.model.eval()\n",
    "        return self.forward(obs)\n",
    "    \n",
    "    \n",
    "    #单步骤采样    \n",
    "    def sample(self, obs):\n",
    "        sample = np.random.rand()  # 产生0~1之间的小数\n",
    "        if sample < self.e_greed:\n",
    "            action = np.random.randint(self.model.action_dim)  # 探索：每个动作都有概率被选择\n",
    "        else:\n",
    "            action = self.predict(obs)  # 选择最优动作\n",
    "        self.e_greed = max(\n",
    "            0.01, self.e_greed - self.e_greed_decrement)  # 随着训练逐步收敛，探索的程度慢慢降低\n",
    "        return action\n",
    "    \n",
    "    #单步骤预测   \n",
    "    def predict(self, obs):  # 选择最优动作\n",
    "        obs = np.expand_dims(obs, axis=0)\n",
    "        tensor = torch.tensor(obs,dtype=torch.float32).to(self.model.fc1.weight.device)\n",
    "        pred_Q = self.predict_batch(tensor)\n",
    "        action = torch.argmax(pred_Q,1,keepdim=True).cpu().numpy()  \n",
    "        action = np.squeeze(action)\n",
    "        return action\n",
    "    \n",
    "    \n",
    "    def sync_target(self):\n",
    "        \"\"\" 把 self.model 的模型参数值同步到 self.target_model\n",
    "        \"\"\"\n",
    "        self.target_model.load_state_dict(self.model.state_dict())\n",
    "    \n",
    "\n",
    "    def compute_loss(self, obs, action, reward, next_obs, done):\n",
    "        \n",
    "        # 每隔200个training steps同步一次model和target_model的参数\n",
    "        if self.global_step % self.update_target_steps == 0:\n",
    "            self.sync_target()\n",
    "        self.global_step += 1\n",
    "        \n",
    "        \n",
    "        # 从target_model中获取 max Q' 的值，用于计算target_Q\n",
    "        self.target_model.eval()\n",
    "        next_pred_value = self.target_model(next_obs)\n",
    "        best_value = torch.max(next_pred_value, dim = 1,keepdim=True).values \n",
    "        target = reward.reshape((-1,1)) + (\n",
    "            torch.tensor(1.0) - done.reshape(-1,1)) * self.gamma * best_value\n",
    "        \n",
    "        #print(\"best_value\",best_value.shape)\n",
    "        #print(\"target\",target.shape)\n",
    "\n",
    "        # 获取Q预测值\n",
    "        self.model.train()\n",
    "        pred_value = self.model(obs)  \n",
    "        action_onehot = F.one_hot(action.reshape(-1),\n",
    "                num_classes = self.model.action_dim).float()\n",
    "        prediction = torch.sum(pred_value*action_onehot,dim= 1,keepdim=True)\n",
    "        \n",
    "        #print(\"pred_value\",pred_value.shape)\n",
    "        #print(\"action_onehot\",action_onehot.shape)\n",
    "        #print(\"prediction\",prediction.shape)\n",
    "        \n",
    "        # 计算 Q(s,a) 与 target_Q的均方差，得到loss\n",
    "        loss = F.smooth_l1_loss(target,prediction)\n",
    "        return loss \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "9cded035-1714-48bf-a772-ab94d1f9e831",
   "metadata": {},
   "outputs": [],
   "source": [
    "agent = DQNAgent(model,gamma=0.9,e_greed=0.1,\n",
    "                 e_greed_decrement=0.001) \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "eaf29876-7e8e-4f0a-b6f0-6bcb2b3fea65",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[-0.1596, -0.0481],\n",
       "        [-0.0927,  0.0318]])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "agent.predict_batch(torch.tensor([[2.0,3.0,4.0,2.0],[1.0,2.0,3.0,4.0]]))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "7baa50e3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor(0.5757, grad_fn=<SmoothL1LossBackward0>)\n"
     ]
    }
   ],
   "source": [
    "loss = agent.compute_loss(torch.tensor([[2.0,3.0,4.0,2.0],[1.0,2.0,3.0,4.0],[1.0,2.0,3.0,4.0]]),\n",
    "          torch.tensor([[1],[0],[0]]),\n",
    "          torch.tensor([[1.0],[1.0],[1.0]]),\n",
    "         torch.tensor([[2.0,3.0,0.4,2.0],[1.0,2.0,3.0,4.0],[1.0,2.0,3.0,4.0]]),\n",
    "         torch.tensor(0.9))\n",
    "print(loss)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "109152db-ed87-4f35-80b1-61b99bd00c3f",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "93668346-2510-416b-b695-926b7a52074a",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "efcec74b",
   "metadata": {},
   "source": [
    "### 三，训练Agent "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "840ee7f4",
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "import collections\n",
    "import numpy as np\n",
    "\n",
    "LEARN_FREQ = 5 # 训练频率，不需要每一个step都learn，攒一些新增经验后再learn，提高效率\n",
    "MEMORY_SIZE = 2048    # replay memory的大小，越大越占用内存\n",
    "MEMORY_WARMUP_SIZE = 512  # replay_memory 里需要预存一些经验数据，再开启训练\n",
    "BATCH_SIZE = 128   # 每次给agent learn的数据数量，从replay memory随机里sample一批数据出来\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "4c2e7709",
   "metadata": {},
   "outputs": [],
   "source": [
    "#经验回放\n",
    "class ReplayMemory(object):\n",
    "    def __init__(self, max_size):\n",
    "        self.buffer = collections.deque(maxlen=max_size)\n",
    "\n",
    "    # 增加一条经验到经验池中\n",
    "    def append(self, exp):\n",
    "        self.buffer.append(exp)\n",
    "\n",
    "    # 从经验池中选取N条经验出来\n",
    "    def sample(self, batch_size):\n",
    "        mini_batch = random.sample(self.buffer, batch_size)\n",
    "        obs_batch, action_batch, reward_batch, next_obs_batch, done_batch = [], [], [], [], []\n",
    "\n",
    "        for experience in mini_batch:\n",
    "            s, a, r, s_p, done = experience\n",
    "            obs_batch.append(s)\n",
    "            action_batch.append(a)\n",
    "            reward_batch.append(r)\n",
    "            next_obs_batch.append(s_p)\n",
    "            done_batch.append(done)\n",
    "\n",
    "        return np.array(obs_batch).astype('float32'), \\\n",
    "            np.array(action_batch).astype('int64'), np.array(reward_batch).astype('float32'),\\\n",
    "            np.array(next_obs_batch).astype('float32'), np.array(done_batch).astype('float32')\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self.buffer)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c5d2a816-2ae5-4395-bb48-c95460338f1b",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "8ef47dae-5e61-4e69-9834-133e7fdf8c44",
   "metadata": {},
   "outputs": [],
   "source": [
    "from torch.utils.data import IterableDataset,DataLoader  \n",
    "class MyDataset(IterableDataset):\n",
    "    def __init__(self,env,agent,rpm,stage='train',size=200):\n",
    "        self.env = env\n",
    "        self.agent = agent \n",
    "        self.rpm = rpm if stage=='train' else None\n",
    "        self.stage = stage\n",
    "        self.size = size \n",
    "        \n",
    "    def __iter__(self):\n",
    "        obs,info = self.env.reset() # 重置环境, 重新开一局（即开始新的一个episode）\n",
    "        step = 0\n",
    "        batch_reward_true = [] #记录真实的reward\n",
    "        while True:\n",
    "            step += 1\n",
    "            action = self.agent.sample(obs) \n",
    "            next_obs, reward, done, _, _ = self.env.step(action) # 与环境进行一个交互\n",
    "            batch_reward_true.append(reward)\n",
    "            \n",
    "            if self.stage=='train':\n",
    "                self.rpm.append((obs, action, reward, next_obs, float(done)))\n",
    "                if (len(rpm) > MEMORY_WARMUP_SIZE) and (step % LEARN_FREQ == 0):\n",
    "                    #yield batch_obs, batch_action, batch_reward, batch_next_obs,batch_done\n",
    "                    yield self.rpm.sample(BATCH_SIZE),sum(batch_reward_true)\n",
    "                    batch_reward_true.clear()\n",
    "            \n",
    "            else:\n",
    "                obs_batch = np.array([obs]).astype('float32')\n",
    "                action_batch = np.array([action]).astype('int64')\n",
    "                reward_batch = np.array([reward]).astype('float32')\n",
    "                next_obs_batch = np.array([next_obs]).astype('float32')\n",
    "                done_batch = np.array([float(done)]).astype('float32')\n",
    "                batch_data = obs_batch,action_batch,reward_batch,next_obs_batch,done_batch\n",
    "                yield batch_data,sum(batch_reward_true)\n",
    "                batch_reward_true.clear()\n",
    "            \n",
    "    \n",
    "            if self.stage =='train':\n",
    "                next_action = self.agent.sample(next_obs) # 训练阶段使用探索策略\n",
    "            else:\n",
    "                next_action = self.agent.predict(next_obs) # 验证阶段使用模型预测结果\n",
    " \n",
    "            action = next_action\n",
    "            obs = next_obs   \n",
    "\n",
    "            if done:\n",
    "                if self.stage=='train' and len(self.rpm)<MEMORY_WARMUP_SIZE: #确保训练一次\n",
    "                    yield self.rpm.sample(len(self.rpm)),sum(batch_reward_true)\n",
    "                    batch_reward_true.clear()\n",
    "                    break\n",
    "                else:\n",
    "                    break\n",
    "    def __len__(self):\n",
    "        return self.size \n",
    "    \n",
    "\n",
    "env = gym.make('CartPole-v1') \n",
    "rpm = ReplayMemory(MEMORY_SIZE)\n",
    "\n",
    "ds_train = MyDataset(env,agent,rpm,stage='train',size=1000)\n",
    "ds_val = MyDataset(env,agent,rpm,stage='val',size=200)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "e2c5f16c-85b3-4e5d-9a2e-d5a3765a8b78",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "13\n",
      "23\n",
      "36\n",
      "47\n",
      "59\n",
      "71\n",
      "81\n",
      "94\n",
      "108\n",
      "119\n",
      "131\n",
      "144\n",
      "154\n",
      "167\n",
      "180\n",
      "191\n",
      "203\n",
      "215\n",
      "225\n",
      "238\n",
      "248\n",
      "257\n",
      "272\n",
      "286\n",
      "299\n",
      "311\n",
      "322\n",
      "332\n",
      "342\n",
      "354\n",
      "364\n",
      "376\n",
      "388\n",
      "401\n",
      "415\n",
      "428\n",
      "438\n",
      "450\n",
      "462\n",
      "475\n",
      "489\n",
      "499\n",
      "511\n",
      "516\n",
      "521\n"
     ]
    }
   ],
   "source": [
    "#ReplayMemory预存数据\n",
    "while len(ds_train.rpm)<MEMORY_WARMUP_SIZE:\n",
    "    for data in ds_train:\n",
    "        print(len(ds_train.rpm))\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "53a73e72-ce44-4e47-8156-167a22e4c7f6",
   "metadata": {},
   "outputs": [],
   "source": [
    "def collate_fn(batch):\n",
    "    samples,rewards = [x[0] for x in batch],[x[-1] for x in batch] \n",
    "    samples = [torch.from_numpy(np.concatenate([x[j] for x in samples])) for j in range(5)] \n",
    "    rewards = torch.from_numpy(np.array([sum(rewards)]).astype('float32'))\n",
    "    return samples,rewards \n",
    "\n",
    "dl_train = DataLoader(ds_train,batch_size=1,collate_fn=collate_fn)\n",
    "dl_val = DataLoader(ds_val,batch_size=1,collate_fn=collate_fn)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "c8980d2c-0ee9-404f-8d15-eb9ef2af6985",
   "metadata": {},
   "outputs": [],
   "source": [
    "for batch in dl_train:\n",
    "    break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "70436e9a",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys,datetime\n",
    "from tqdm import tqdm\n",
    "import numpy as np\n",
    "from accelerate import Accelerator\n",
    "from torchkeras import KerasModel\n",
    "import pandas as pd \n",
    "\n",
    "from copy import deepcopy\n",
    "\n",
    "class StepRunner:\n",
    "    def __init__(self, net, loss_fn, accelerator=None, stage = \"train\", metrics_dict = None, \n",
    "                 optimizer = None, lr_scheduler = None\n",
    "                 ):\n",
    "        self.net,self.loss_fn,self.metrics_dict,self.stage = net,loss_fn,metrics_dict,stage\n",
    "        self.optimizer,self.lr_scheduler = optimizer,lr_scheduler\n",
    "        self.accelerator = accelerator if accelerator is not None else Accelerator()\n",
    "    \n",
    "    def __call__(self, batch):\n",
    "        \n",
    "        samples,reward = batch\n",
    "        #torch_data = ([torch.from_numpy(x) for x in batch_data])\n",
    "        loss = self.net.compute_loss(*samples)\n",
    "        \n",
    "        #backward()\n",
    "        if self.optimizer is not None and self.stage==\"train\":\n",
    "            self.accelerator.backward(loss)\n",
    "            if self.accelerator.sync_gradients:\n",
    "                self.accelerator.clip_grad_norm_(self.net.parameters(), 1.0)\n",
    "            self.optimizer.step()\n",
    "            if self.lr_scheduler is not None:\n",
    "                self.lr_scheduler.step()\n",
    "            self.optimizer.zero_grad()\n",
    "                \n",
    "            \n",
    "        #losses （or plain metric）\n",
    "        step_losses = {self.stage+'_reward':reward.item(), \n",
    "                       self.stage+'_loss':loss.item()}\n",
    "        \n",
    "        #metrics (stateful metric)\n",
    "        step_metrics = {}\n",
    "        if self.stage==\"train\":\n",
    "            if self.optimizer is not None:\n",
    "                step_metrics['lr'] = self.optimizer.state_dict()['param_groups'][0]['lr']\n",
    "            else:\n",
    "                step_metrics['lr'] = 0.0\n",
    "        return step_losses,step_metrics\n",
    "    \n",
    "\n",
    "class EpochRunner:\n",
    "    def __init__(self,steprunner,quiet=False):\n",
    "        self.steprunner = steprunner\n",
    "        self.stage = steprunner.stage\n",
    "        self.accelerator = steprunner.accelerator\n",
    "        self.net = steprunner.net\n",
    "        self.quiet = quiet\n",
    "        \n",
    "    def __call__(self,dataloader):\n",
    "        dataloader.agent = self.net \n",
    "        n = dataloader.size  if hasattr(dataloader,'size') else len(dataloader)\n",
    "        loop = tqdm(enumerate(dataloader,start=1), \n",
    "                    total=n,\n",
    "                    file=sys.stdout,\n",
    "                    disable=not self.accelerator.is_local_main_process or self.quiet,\n",
    "                    ncols=100\n",
    "                   )\n",
    "        epoch_losses = {}\n",
    "        for step, batch in loop: \n",
    "            if step<n:\n",
    "                step_losses,step_metrics = self.steprunner(batch)   \n",
    "                step_log = dict(step_losses,**step_metrics)\n",
    "                for k,v in step_losses.items():\n",
    "                    epoch_losses[k] = epoch_losses.get(k,0.0)+v\n",
    "                loop.set_postfix(**step_log) \n",
    "            else:\n",
    "                break\n",
    "            \n",
    "        epoch_metrics = step_metrics\n",
    "        epoch_metrics.update({self.stage+\"_\"+name:metric_fn.compute().item() \n",
    "                         for name,metric_fn in self.steprunner.metrics_dict.items()})\n",
    "        epoch_losses = {k:v for k,v in epoch_losses.items()}\n",
    "        epoch_log = dict(epoch_losses,**epoch_metrics)\n",
    "        loop.set_postfix(**epoch_log)\n",
    "\n",
    "        for name,metric_fn in self.steprunner.metrics_dict.items():\n",
    "            metric_fn.reset()\n",
    "            \n",
    "        return epoch_log\n",
    "    \n",
    "KerasModel.StepRunner = StepRunner\n",
    "KerasModel.EpochRunner = EpochRunner \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "49957914",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[0;31m<<<<<< 🐌 cpu is used >>>>>>\u001b[0m\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 600x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<style>\n",
       "    /* background: */\n",
       "    progress::-webkit-progress-bar {background-color: #CDCDCD; width: 100%;}\n",
       "    progress {background-color: #CDCDCD;}\n",
       "\n",
       "    /* value: */\n",
       "    progress::-webkit-progress-value {background-color: #00BFFF  !important;}\n",
       "    progress::-moz-progress-bar {background-color: #00BFFF  !important;}\n",
       "    progress {color: #00BFFF ;}\n",
       "\n",
       "    /* optional */\n",
       "    .progress-bar-interrupted, .progress-bar-interrupted::-webkit-progress-bar {\n",
       "        background: #000000;\n",
       "    }\n",
       "</style>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "\n",
       "    <div>\n",
       "      <progress value='297' class='progress-bar-interrupted' max='600' style='width:300px; height:20px; vertical-align: middle;'></progress>\n",
       "      49.50% [297/600 00:32<00:33][earlystopping]\n",
       "      <br>\n",
       "      \n",
       "    </div>\n",
       "    "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[0;31m<<<<<< val_reward without improvement in 100 epoch,early stopping >>>>>>\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "keras_model = KerasModel(net= agent,loss_fn=None,\n",
    "        optimizer=torch.optim.Adam(agent.model.parameters(),lr=1e-2))\n",
    "\n",
    "dfhistory = keras_model.fit(train_data = dl_train,\n",
    "    val_data=dl_val,\n",
    "    epochs=600,\n",
    "    ckpt_path='checkpoint.pt',\n",
    "    patience=100,\n",
    "    monitor='val_reward',\n",
    "    mode='max',\n",
    "    callbacks=None,\n",
    "    plot= True,\n",
    "    cpu=True)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "42b48153",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "475e96d4",
   "metadata": {},
   "source": [
    "### 四，评估Agent "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "51a68f2d-785b-432a-a93c-7af94a7c63ff",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 评估 agent, 跑 3 次，总reward求平均\n",
    "def evaluate(env, agent, render=False):\n",
    "    eval_reward = []\n",
    "    for i in range(2):\n",
    "        obs,info = env.reset()\n",
    "        episode_reward = 0\n",
    "        step=0\n",
    "        while step<300:\n",
    "            action = agent.predict(obs)  # 预测动作，只选最优动作\n",
    "            obs, reward, done, _, _ = env.step(action)\n",
    "            episode_reward += reward\n",
    "            if render:\n",
    "                show_state(env,step,info='reward='+str(episode_reward))\n",
    "            if done:\n",
    "                break\n",
    "            step+=1\n",
    "        eval_reward.append(episode_reward)\n",
    "    return np.mean(eval_reward)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "2b2476b3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAgMAAAF0CAYAAAC+FDqzAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAdh0lEQVR4nO3dfXTT5f3/8dcnSZu0AQpFaIGBChSsxYEU5cfd3MQ7YAITReYNRXcGQhGHX0F23BlsyiaKwoSBgEw2b75uON2Zc9PBRCyICogMFQbe61BQoEVK6U3y/v2B5EtMaYu2DXI9H+dwPL1yfZIrKcc8ufJJ4pmZCQAAOMuX7AUAAIDkIgYAAHAcMQAAgOOIAQAAHEcMAADgOGIAAADHEQMAADiOGAAAwHHEAAAAjiMGAJyQZsyYIc/zkr0MwAnEAE5Yjz76qObOnZvsZSRYv369Jk6cqLy8PIXDYXXo0EEjR47U9u3bq50/f/585ebmKhgMql27drr55ptVWlqaMO+tt97S5ZdfrhYtWig9PV39+/fXqlWrGvruOGHy5Mnq2bOnMjMzlZ6ertzcXM2YMUMHDhxImFteXq5bb71Vbdu2VVpamnr37q0VK1ZUe70vvvii+vfvr/T0dGVnZ2vSpEnVXuexLF26VLm5uQqFQsrJydG8efO+8n0EvhYDTlBDhgyxU089NdnLSDBixAjLzs62G2+80ZYsWWK33367ZWVlWTgcti1btsTNnTp1qkmyyy+/3BYuXGg33nijBQIBu+iii+LmffDBB3bKKadYVlaWzZw50+bOnWvdu3e3QCBgq1evbsy7d8KYPn261df/ovr162eTJk2y++67zxYvXmzjx4+3YDBo/fr1s0gkEjd31KhRFggE7JZbbrFFixZZnz59LBAIWFFRUdy8TZs2WSgUsrPPPtsWLlxot912mwWDQbvkkkvqtKb777/fJNmIESNs8eLFdu2115oku/POO+vlPgPHgxjACetEjYG1a9daeXl53Nj27dstGAza1VdfHRvbuXOnBQIBu/baa+Pmzps3zyTZX//619jYhAkTLBAI2LZt22JjpaWl1r59e+vZs+dXWueBAwe+0nGNpbKyMuFxPFp9xkB1Zs+ebZJs3bp1sbGXX37ZJNndd98dGysrK7NOnTpZnz594o4fNGiQtWnTxkpKSmJjS5YsMUn27LPP1njbBw8etJYtW9qQIUPixq+++moLh8O2d+/er3PXgOPGywRIis8//1w/+clPdNpppykYDKp169a68MIL9eqrr0qSvvvd7+rpp5/W+++/L8/z5HmeTjvttNjx5eXlmj59ujp37qxgMKj27dtr6tSpKi8vj7sdz/M0ceJEPfLII+ratatCoZDy8/P1wgsvJKxp27Zt+uCDD2pde9++fZWamho3lpOTo7y8PG3dujU2tm7dOlVVVWnUqFFxc4/8/Nhjj8XGioqKdPbZZ6tr166xsfT0dA0dOlSvvvqqduzYUeOaxowZoyZNmujtt9/W4MGD1bRpU1199dWSpGg0qrlz5yovL0+hUEhZWVkaN26c9u3bFzv+5ptvVsuWLWVHfYnpjTfeKM/zdN9998XGdu3aJc/ztHDhQklSRUWFfv7znys/P18ZGRkKh8MaMGBAwssb7733njzP0+zZszV37lx16tRJwWBQb775piRpzZo1OueccxQKhdSpUyctWrSoxvtbH478fSouLo6NPf744/L7/Ro7dmxsLBQK6Uc/+pHWrVunDz/8UJK0f/9+rVixQtdcc42aNWsWmzt69Gg1adJEf/rTn2q87VWrVmnPnj2aMGFC3HhhYaFKS0v19NNPf817BxyfQLIXADfdcMMNevzxxzVx4kSdeeaZ2rNnj9asWaOtW7eqZ8+euu2221RSUqKPPvpIc+bMkSQ1adJE0uEnt6FDh2rNmjUaO3ascnNztWXLFs2ZM0fbt2/XX/7yl7jbWr16tf74xz9q0qRJCgaDWrBggS655BK98sor6tatW2xebm6uzjvvPD3//PPHfX/MTLt27VJeXl5s7EiYpKWlxc1NT0+XJG3cuDFubosWLRKu9+i5OTk5Na6hqqpKF198sfr376/Zs2fHjh03bpyWLVum6667TpMmTdK7776r+fPna9OmTVq7dq1SUlI0YMAAzZkzR2+88UbsMSkqKpLP51NRUZEmTZoUG5Ok73znO5IOPyk+8MAD+uEPf6gf//jH+vzzz7V06VJdfPHFeuWVV9SjR4+4NT744IM6dOiQxo4dq2AwqMzMTG3ZskUXXXSRWrVqpRkzZqiqqkrTp09XVlZWwn0sKSlRZWVljY+DdPgJ/Mjfl6Mfn+LiYlVUVOj111/Xz372MzVt2lTnnntubM6mTZvUpUuXuCd4SbE5r732mtq3b68tW7aoqqpKvXr1ipuXmpqqHj16aNOmTTWu78jlXz4+Pz9fPp9PmzZt0jXXXFPr/QTqTbK3JuCmjIwMKywsrHHOsV4meOihh8zn8yW8hnvkNdi1a9fGxiSZJNuwYUNs7P3337dQKGQ/+MEP4o6XZOedd97x35kv1iTJli5dGhvbuHGjSbLbb789bu4zzzxjkqxJkyaxsUsvvdSaN29u+/fvj5vbp08fk2SzZ8+u8fYLCgpMkk2bNi1uvKioyCTZI488Uu0ajozv3r3bJNmCBQvMzKy4uNh8Pp9dccUVlpWVFTtu0qRJlpmZadFo1MzMqqqqErb69+3bZ1lZWXb99dfHxt59912TZM2aNbPdu3fHzR8+fLiFQiF7//33Y2Nvvvmm+f3+hJcJzjvvvNjvtKY/BQUFCY/RunXr4uZ07drVVq1aFTcnLy/Pzj///IRj33jjDZNk999/v5mZLV++3CTZCy+8kDD3iiuusOzs7ITxoxUWFprf76/2slatWtmoUaNqPB6ob+wMICmaN2+ul19+WTt37lTbtm2P69jly5crNzdXZ5xxhj777LPY+Pnnny/p8BZs3759Y+N9+vRRfn5+7OcOHTpo2LBheuqppxSJROT3+yUpbov8eGzbtk2FhYXq06ePCgoKYuM9e/ZU7969NWvWLLVr107f+973tHXrVo0fP14pKSkqKyuLzR0/fryeeuopXXnllZo5c6bC4bAWLFigDRs2SFLc3JqMHz8+7ufly5crIyNDF154YdxjlZ+fryZNmmjVqlW66qqr1KpVK51xxhl64YUXNH78eK1du1Z+v19TpkzR8uXLtWPHDuXk5KioqEj9+/ePveXP7/fHHr9oNKri4mJFo1H16tUr9pLP0UaMGKFWrVrFfo5EInr22Wc1fPhwdejQITaem5uriy++WH//+9/jjr/nnnviXt44lur+Tp155plasWKFSktL9eKLL2rlypUJZ/6XlZUpGAwmHBsKhWKXH/3fY82t7fdVVlaW8FLT8RwP1DdiAElx1113qaCgQO3bt1d+fr4GDx6s0aNHq2PHjrUeu2PHDm3dujXuSeVou3fvjvu5uu31Ll266ODBg/r000+VnZ391e6EpE8++URDhgxRRkZG7PXmo/35z3/WlVdeqeuvv17S4SfPm2++WatXr9Z//vOf2LxBgwZp3rx5mjZtmnr27ClJ6ty5s2bOnKmpU6cmbHlXJxAI6Fvf+lbc2I4dO1RSUqLWrVtXe8zRj9WAAQNiT75FRUXq1auXevXqpczMTBUVFSkrK0ubN2/WVVddFXcdv//973XPPfdo27ZtcVv4p59+esLtfXns008/VVlZWbW/o65duybEwNFRd7yaNWumCy64QJI0bNgwPfrooxo2bJheffVVde/eXdLhl3S+fN6JJB06dCh2+dH/PdbcL7809GVpaWmqqKio9rK6HA/UN2IASTFy5EgNGDBATz75pP75z3/q7rvv1qxZs/TEE09o0KBBNR4bjUZ11lln6d5776328vbt2zfEkhOUlJRo0KBBKi4uVlFRUbX/Gm3Xrp3WrFmjHTt26JNPPlFOTo6ys7PVtm1bdenSJW7uxIkTdd111+nf//537LXnpUuXSlLC3OoEg0H5fPHnBEejUbVu3VqPPPJItcccHVT9+/fXkiVL9M4776ioqEgDBgyQ53nq379/7P5Fo1ENGDAgdszDDz+sMWPGaPjw4ZoyZYpat24tv9+vX//613r77bcTbu/rPsnt3bv3mE+iX76djIyMGudcdtlluvbaa/XYY4/FYqBNmzb673//mzD3448/lvR/Ow5t2rSJG//y3Np2u9q0aaNIJKLdu3fHhVpFRYX27Nlz3LtlwNdFDCBp2rRpowkTJmjChAnavXu3evbsqZkzZ8Zi4FifPtepUydt3rxZAwcOrNMn1FV3Jv727duVnp5+zN2F2hw6dEiXXnqptm/frpUrV+rMM8+scX5OTk7sX79vvvmmPv74Y40ZMyZhXjgcVp8+fWI/r1y5UmlpaerXr99XWmenTp20cuVK9evXr9Yn4iNP8itWrND69es1bdo0SYdPFly4cKHatm2rcDgc96/zxx9/XB07dtQTTzwR97uYPn16ndbXqlUrpaWlVfs7Onrn5IjLLrtMq1evrvV6CwoKtGzZshrnlJeXKxqNqqSkJDbWo0cPrVq1Svv37487ifDll1+OXS5J3bp1UyAQ0IYNGzRy5MjYvIqKCr322mtxY9U5cj0bNmzQ4MGDY+MbNmxQNBpNOPESaHDJPmkB7qmqqrLi4uKE8XPOOcd69eoV+/nKK6+05s2bJ8xbtmyZSbJFixYlXHbw4MG499fri5PFNm7cGBv74IMPLBQK2fDhw+OO3bp1a9xJbDWtf+jQoRYIBOzpp5+udf7RIpGIDRkyxNLT02u9rbVr15rf77eJEyfWer0FBQUWDocTxp9//nmTZD/96U8TLqusrLR9+/bFjbVr1866du1qnufF3ut+5L33Xbp0sYEDB8bNv+yyy6xjx45xH9zz0ksvmed5cSd/HjmB8Oj37x9xPCcQbtiwwVasWFHrnzfeeCN2zL59+6yioiLhdo98zsDRJ32+9NJLCes8dOiQde7c2Xr37h13/CWXXGJt2rSJO+nzgQceMEn2j3/8IzZWWlpqW7dutU8//TQ2dvDgQcvMzLTvf//7cdd5zTXXWHp6uu3ZsydhvUBDIgbQ6Pbt22fhcNgKCgrs3nvvtcWLF9vIkSNNkt1zzz2xeXfddZdJssmTJ9ujjz4a+5CeSCRigwcPNs/zbNSoUTZv3jybO3eu3XDDDZaZmWnr16+PXYck69atm51yyin2y1/+0mbNmmWnnnqqhUIh27x5c9y6VMd3E9x0000myS699FJ76KGHEv4cbdKkSTZ27FhbsGCB/eY3v7HevXub53n2hz/8IW7ee++9Z+eee67dcccd9sADD9jkyZMtLS3Nzj777IR3GFTnWDFgZjZu3DiTZIMGDbI5c+bY/Pnz7aabbrK2bdva8uXL4+aOGjXKJNlZZ50VG6usrLRwOGySbMaMGXHzf/e735kkGzp0qC1atMimTZtmzZs3t7y8vDrHwObNmy0UClmHDh3szjvvtDvuuMOysrLs29/+dr186NCTTz5p7du3t8mTJ9uCBQts7ty5NmLECPM8z3r16pXwbogrrrjCAoGATZkyxRYtWmR9+/at9pMgN27caMFgMO4TCEOhUMKnS65atcok2fTp0+PGf/vb38Y+nXLJkiU2evRok2QzZ8782vcZOF7EABpdeXm5TZkyxbp3725Nmza1cDhs3bt3j72t7YgDBw7YVVddZc2bNzdJcU8uFRUVNmvWLMvLy7NgMGgtWrSw/Px8+8UvfhH3iXCSrLCw0B5++GHLycmJ/c/7y28pOzK3LjFQ29vbjvbggw9a9+7dLRwOW9OmTW3gwIH23HPPJVzn3r17bdiwYZadnW2pqal2+umn26233lqnEDCrOQbMzBYvXmz5+fmWlpZmTZs2tbPOOsumTp1qO3fujJt35Alq/PjxceMXXHCBSbJ//etfcePRaNR+9atf2amnnhp7bP/2t79ZQUFBnWPAzGz16tWWn59vqamp1rFjR7v//vvr7RMI33rrLRs9erR17NjR0tLSLBQKWV5enk2fPr3aT2ksKyuzW265xbKzsy0YDNo555xjzzzzTLXXXVRUZH379rVQKGStWrWywsLChN/ZsWLA7PDvpWvXrpaammqdOnWyOXPmxN62CTQmz+wrvp8K+AbwPE+FhYWaP39+spcCACcsPo4YAADHEQMAADiOGAAAwHF8zgBOapwSAwC1Y2cAAADHEQMAADiOGAAAwHHEAAAAjiMGAABwHDEAAIDjiAEAABxHDAAA4DhiAAAAxxEDAAA4jhgAAMBxxAAAAI4jBgAAcBwxAACA44gBAAAcRwwAAOA4YgAAAMcRAwAAOI4YAADAccQAAACOIwYAAHAcMQAAgOOIAQAAHEcMAADgOGIAAADHEQMAADiOGAAAwHHEAAAAjiMGAABwHDEAAIDjiAEAABxHDAAA4DhiAAAAxxEDAAA4jhgAAMBxxAAAAI4jBgAAcBwxAACA44gBAAAcRwwAAOA4YgAAAMcRAwAAOI4YAADAccQAAACOIwYAAHAcMQAAgOOIAQAAHEcMAADgOGIAAADHEQMAADiOGAAAwHHEAAAAjiMGAABwHDEAAIDjiAEAABxHDAAA4DhiAAAAxxEDAAA4jhgAAMBxxAAAAI4jBgAAcBwxAACA44gBAAAcRwwAAOA4YgAAAMcRAwAAOI4YAADAccQAAACOIwYAAHAcMQAAgOOIAQAAHEcMAADgOGIAAADHEQMAADiOGAAAwHHEAAAAjiMGAABwHDEAAIDjiAEAABxHDAAA4DhiAAAAxxEDAAA4jhgAAMBxxAAAAI4jBgAAcBwxAACA44gBAAAcRwwAAOA4YgAAAMcRAwAAOI4YAADAccQAAACOIwYAAHAcMQAAgOOIAQAAHEcMAADgOGIAAADHEQMAADiOGAAAwHHEAAAAjiMGAABwHDEAAIDjiAEAABxHDAAA4DhiAAAAxxEDAAA4jhgAAMBxxAAAAI4jBgAAcBwxAACA44gBAAAcRwwAAOA4YgAAAMcRAwAAOI4YAADAccQAAACOIwYAAHAcMQAAgOOIAQAAHEcMAADgOGIAAADHEQMAADiOGAAAwHHEAAAAjiMGAABwHDEAAIDjiAEAABxHDAAA4DhiAAAAxxEDAAA4jhgAAMBxxAAAAI4jBgAAcBwxAACA44gBAAAcRwwAAOA4YgAAAMcRAwAAOI4YAADAccQAAACOIwYAAHAcMQAAgOOIAQAAHEcMAADguECyFwAAwMlu15bnVPLRGzXOadn5XLXM6d1IK4pHDAAA0ICikYhKP3tfJR9sqXFeuNWpjbSiRLxMAABAA7JopSxSlexl1IgYAACgAVmkStEoMQAAgLOikSp2BgAAcJkRAwAAuC0arVKUGAAAwF2R8oOKVByscY7nC8gXCDbSihIRAwAANKCDez9S2d7/1jgn2LSlmmR1bKQVJSIGAABIMs/nl+dPSdrtEwMAACSZ5/fLFyAGAABwlucLyOdPTdrtEwMAACSZ52NnAAAAp3k+v3ycMwAAgLs8n18eOwMAAJx8zEyy2ud5Ph87AwAAnJQsqmhVRR0mevI8r8GXcyzEAAAADcTqHAPJRQwAANBALEoMAADgNnYGAABwm0WjilSWJ3sZtSIGAABoIGZRGTsDAAC4K1pZrvLPP6t5kudTarhF4yzoGIgBAAAaSNWhAzqw6+0a5/hTgmr2rTMbaUXVIwYAAEgmz5M/JZjUJRADAAAkkSdPPmIAAACHeZ78KaGkLoEYAAAgmTwfOwMAALjMY2cAAADXcQIhAAAnJTOTWbT2iZ4nL4lfXywRAwAANJhI5aE6zUvm1xdLxAAAAA3EFKmoWwwkGzEAAEBDMClSUZbsVdQJMQAAQIOwb8Q3FkrEAAAADSZayc4AAADOMuOcAQAA3GZRHdj9Tq3T0k/p0AiLqRkxAABAA7BoVAc+3lHrvIz23RphNTUjBgAASCJ/alqyl0AMAACQTIEgMQAAgNPYGQAAwGnJ/8ZCiRgAACCp/KnpyV4CMQAAQMOwOs3yB9kZAADgpBSNVNVpns+f2sArqcMakr0AAABORnX9+uITATEAAEADiJR/M76XQCIGAABoEJFvyJcUScQAAAANgp0BAAAcF6k4mOwl1BkxAABAA4hUsDMAAIDTij98vdY5TdvmyPO8RlhNzYgBAAAaQOnu92qd0ySrsyRiAAAAZ/lT006EFiAGAABIlhPhGwslYgAAgKQ5HAPJ3xogBgAASBJ2BgAAcJw/NfnfWCgRAwAA1DuzOn59cQoxAADASSkaqZRUexB4Pj+fMwAAwMkoWllelxY4YRADAADUs0jFIX2TaoAYAACgnkUqD9X5vIETATEAAEA9i1SyMwAAgNOiFYe+SS1ADAAAUN/YGQAAwHElH77+xdsLj61Jdmc+gRAAgJNV+f7PpFpOIAxlZMkXSG2kFdWMGAAAIAl8KcET4gOHJGIAAICk8AWCkndiPA2fGKsAAMAx/pRUdgYAAHCZLyXEzgAAAC7zB1LlEQMAAJx86voxxIfPGeBlAgAATjoWqZIsWvtEz+OcAQAATkbRqgpZNJLsZRwXYgAAgHoUjVTI6rIzcAIhBgAAqEfRSnYGAABw2uGXCdgZAADAWYdfJmBnAAAAZ0WrKtkZAADAZZ9/vEOVpcU1zklv2V6hjNaNs6A6IAYAAKhHkYqDsmhVjXMCoSbyp6Y30opqRwwAANDIPH+KPL8/2cuIIQYAAGhkvkCKfL5AspcRQwwAANDIPH+AnQEAAFzm86fIY2cAAAB3+fwBeT52BgAAOOmYWZ2+wtjzEQMAAJyULBo5/BXGtTmBvr5YIgYAAKg3FqlStC4xcII5cc5eAAAgycxMkchX/16BqspyRasqar+daFRVVV8vGvx+f73tLnhWlxc3AABwQElJiU455ZSvfHzLZmn6n5H/T9/tcVqN8/73X69r3pPrv/LtSNJnn32mjIyMr3UdR7AzAADAF8zs6/2L3aJK8df+Cny0HnYG6hMxAABAPUkJ+JWacvhdAlHztKvidJVGMiSZwv4SZaW+J5934m3IEwMAANSTlIBPKYHDMfDa5wO1rzJLlZZ2+DKvTJ+kdNLZzVYmc4nV4t0EAADUk45tWij3tCy9uv9C7ao4XRUWlsknk08VFtYnFafr7+/10ctbP072UuMQAwAA1JOA36d3DvXRrorTJFV3pr8nhbupWYcfNPLKakYMAABQrzxVHwJfXOp5NVyaHMQAAACOIwYAAHAcMQAAQD3KCa9Xy5T/SqruLYSmXTtf00trf9fYy6oRMQAAQD0KeFU6p9nTykz5WAHvkKSopKgC3iFlpuxUj7S/qvRgabKXGYfPGQAAoJ589Ol+/WXNNkmS2XZ9VN5Fn1dlSpKaBvbqW8H/6MPdxaqKRJO5zAR1/m6CcePGNfRaAABIqoqKCi1btizZy6iTMWPGKDU1tdZ5ixYtqnVOnWPglVdeqcs0AAC+sQ4cOKCBAwcmexl18txzzykcDtc679xzz611Dt9aCADAF4qLi9WiRYtkL6NOiouL6+1bCzmBEAAAxxEDAAA4jhgAAMBxxAAAAI4jBgAAcBwxAACA44gBAAAcRwwAAOA4YgAAAMcRAwAAOI5vLQQA4AspKSkaPnx4spdRJykpKfV2XXw3AQAAjuNlAgAAHEcMAADgOGIAAADHEQMAADiOGAAAwHHEAAAAjiMGAABwHDEAAIDjiAEAABxHDAAA4DhiAAAAxxEDAAA4jhgAAMBxxAAAAI4jBgAAcBwxAACA44gBAAAcRwwAAOA4YgAAAMcRAwAAOI4YAADAccQAAACOIwYAAHAcMQAAgOOIAQAAHEcMAADgOGIAAADHEQMAADiOGAAAwHHEAAAAjiMGAABwHDEAAIDjiAEAABxHDAAA4DhiAAAAxxEDAAA4jhgAAMBxxAAAAI4jBgAAcBwxAACA44gBAAAcRwwAAOA4YgAAAMcRAwAAOI4YAADAccQAAACOIwYAAHAcMQAAgOOIAQAAHEcMAADgOGIAAADHEQMAADiOGAAAwHHEAAAAjiMGAABwHDEAAIDjiAEAABxHDAAA4DhiAAAAxxEDAAA4jhgAAMBxxAAAAI4jBgAAcBwxAACA44gBAAAcRwwAAOA4YgAAAMcRAwAAOI4YAADAccQAAACOIwYAAHAcMQAAgOOIAQAAHEcMAADgOGIAAADHEQMAADiOGAAAwHHEAAAAjiMGAABw3P8HVUGAOmVhQ28AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "288.5"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#直观显示动画\n",
    "env = gym.make('CartPole-v1',render_mode=\"rgb_array\") \n",
    "\n",
    "evaluate(env, agent, render=True)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "05fd6239",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "cd03379b",
   "metadata": {},
   "source": [
    "### 五，保存Agent "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "211be5cc",
   "metadata": {},
   "outputs": [],
   "source": [
    "torch.save(agent.state_dict(),'dqn_agent.pt')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "14fb3fe0",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "cfa6498a-6a18-4084-9e9f-3ae566283a16",
   "metadata": {},
   "source": [
    "**如果本项目对你有所帮助，想鼓励一下作者，记得给本项目加一颗星星star⭐️，并分享给你的朋友们喔😊!** \n",
    "\n",
    "如果在torchkeras的使用中遇到问题，可以在项目中提交issue。\n",
    "\n",
    "如果想要获得更快的反馈或者与其他torchkeras用户小伙伴进行交流，\n",
    "\n",
    "可以在公众号算法美食屋后台回复关键字：**加群**。\n",
    "\n",
    "![](https://tva1.sinaimg.cn/large/e6c9d24egy1h41m2zugguj20k00b9q46.jpg)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b7a7b8cb",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "jupytext": {
   "cell_metadata_filter": "-all",
   "formats": "md,ipynb",
   "main_language": "python",
   "notebook_metadata_filter": "-all"
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
